package com.iwhalecloud.bss.kite.cucc.spec.impl.transfer;

import java.beans.PropertyDescriptor;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.BeanUtils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts2;
import com.iwhalecloud.bss.kite.common.constant.SwitchConsts;
import com.iwhalecloud.bss.kite.common.constant.SymbolConsts;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteMapUtils;
import com.iwhalecloud.bss.kite.common.util.KiteObjectUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.common.util.SeqUtils;
import com.iwhalecloud.bss.kite.cucc.client.api.attr.IUnicomRegionService;
import com.iwhalecloud.bss.kite.cucc.client.api.goods.IGoodsService;
import com.iwhalecloud.bss.kite.cucc.client.dto.offer.CategoryOfferDTO;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import com.iwhalecloud.bss.kite.cucc.common.constant.TableConsts;
import com.iwhalecloud.bss.kite.cucc.dataservice.cache.CategoryOfferCache;
import com.iwhalecloud.bss.kite.dataservice.cache.AttrValueCache;
import com.iwhalecloud.bss.kite.dataservice.cache.DcPublicCache;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferCache;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferDetailCache;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferFeeDiscntShowRuleCache;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferObjRelRoleCache;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferRelCache;
import com.iwhalecloud.bss.kite.dataservice.cache.ProdFeeCache;
import com.iwhalecloud.bss.kite.dataservice.cache.ProdHisAttrCache;
import com.iwhalecloud.bss.kite.dataservice.entity.AttrValue;
import com.iwhalecloud.bss.kite.dataservice.entity.DcPublic;
import com.iwhalecloud.bss.kite.dataservice.entity.OfferAttr;
import com.iwhalecloud.bss.kite.dataservice.entity.OfferEffExpConfig;
import com.iwhalecloud.bss.kite.dataservice.entity.OfferObjRelRole;
import com.iwhalecloud.bss.kite.dataservice.entity.fee.OfferFeeDiscntShowRule;
import com.iwhalecloud.bss.kite.dataservice.entity.fee.ShowRule;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.Offer;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.OfferDetail;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.OfferRelInfo;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.OfferRestrict;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.ProdHisAttr;
import com.iwhalecloud.bss.kite.dataservice.util.GeneralSwitchUtils;
import com.iwhalecloud.bss.kite.manager.enums.RelType;
import com.ztesoft.bss.base.staticdata.CoreDataOffer;
import com.ztesoft.bss.base.staticdata.CoreDataPublic;
import com.ztesoft.bss.common.util.ContextUtil;
import com.ztesoft.bss.common.util.SpringUtil;
import com.ztesoft.bss.order.base.consts.KeyValues;

/**
 * <Description> 销售品转换 <br>
 *
 * @author huang.caibiao<br>
 * @version 1.0<br>
 * @taskId <br>
 * @date 2020-02-26 <br>
 * @since R9.0<br>
 * @see com.iwhalecloud.bss.kite.cucc.spec.impl.transfer <br>
 */
public class GoodsInfoTransfer {

    public static final String GOODS_TYPE_SALE = "sale";

    public static final String GOODS_TYPE_SINGLE = "single";

    public static final String GOODS_TYPE_GROUP = "group";
    
    public static final String GOODS_TYPE_FUSE = "fuse";

    public static final String VALUE_TYPE_OPTION = "OPTIONS";

    public static final String VALUE_TYPE_INPUT = "INPUT";

    public static final String STATUS_VALID = "VALID";

    private static final String PRODUCT_TYPE_PAY = "pay";

    private static final String PRODUCT_TYPE_ADD = "add";

    public static final String GOODS_TYPE_CLUSTER = "cluster";
    /**
     * 销售品转换
     * @param good
     * @return
     */
    public static Offer convertOffer(Map<String, Object> good) {
        if (Objects.isNull(good)) {
            return null;
        }
        convertFieldValue(good);
        convertField(good, getOfferConvertField());
        Offer offer = KiteMapUtils.mapToBean(good, Offer.class);
        offer.setOfferMap(good);
        return offer;
    }

    /**
     * 销售品属性转换
     * @param good
     * @return
     */
    @SuppressWarnings("unchecked")
    public static List<OfferAttr> convertOfferAttrs(Map<String, Object> good) {
        String cateId = (String) good.get("cateId");
        Offer offer = convertOffer(good);
        List<OfferAttr> offerAttrs = new ArrayList<>();
        //基础商品属性
        List<Map<String, Object>> goodsAttrs = Lists.newArrayList();
        if (KiteStringUtils.equalsAny(offer.getOfferType(),KeyConsts.OFFER_TYPE_11,KeyConsts.OFFER_TYPE_15)) {
            if (good != null) {
                goodsAttrs = (List<Map<String, Object>>) good.get("goodsAttrs");
            }
        }
        else if (KeyConsts.OFFER_TYPE_13.equals(offer.getOfferType())) {
            if (good != null) {
                List<Map> saleGoods = (List<Map>) good.get("saleGoods");
                if (KiteListUtils.isNotEmpty(saleGoods)) {
                    goodsAttrs = (List<Map<String, Object>>) saleGoods.get(0).get("goodsAttrs");
                    /*saleGoods.forEach(singleGood -> {
                        goodsAttrs = (List<Map<String, Object>>) singleGood.get("goodsAttrs");
                    });*/
                }
            }
        }

        offerAttrs.addAll(packageOfferAttr(goodsAttrs, offer.getOfferId()));
        //资费产品信息
        List<Map<String, Object>> productCategroys = (List<Map<String, Object>>) good.get("productCategroy");
        if (KiteListUtils.isNotEmpty(productCategroys)) {
            for (Map<String, Object> productCategroy : productCategroys) {
                if ("pay".equals(KiteMapUtils.getString(productCategroy, "productType"))) {
                    List<Map<String, Object>> products = (List<Map<String, Object>>) productCategroy.get("products");
                    if (KiteListUtils.isNotEmpty(products)) {
                        Map<String, Object> product = products.get(0);
                        //资费产品也存到属性里面
                        offerAttrs.addAll(packageOfferAttr((List<Map<String, Object>>) product.get("productAttrs"), offer.getOfferId()));

                        //资费产品也放进去
                        OfferAttr offerAttr = new OfferAttr();
                        offerAttr.setShowType(KeyConsts.PROD_ATTR_SHOW_TYPE_E);
                        offerAttr.setFieldName("productCode");
                        offerAttr.setDefaultValue(KiteMapUtils.getString(product, "productCode"));
                        offerAttr.setOfferId(offer.getOfferId());
                        offerAttrs.add(offerAttr);
                    }
                    break;
                }
            }
        }
        addCateIdAttr(offerAttrs, offer.getOfferId(), cateId);
        removeProperty(good, offer);

        good.forEach((key, val) -> {
            if (!StringUtils.equalsAny(key, "goodsAttrs", "productCategroy", "saleProvinces", "keyAttrs", "goodsCategroy", "saleGoods", "activities", "goodsItems", "goodsPictrues", "members","historyData")) {
                OfferAttr offerAttr = new OfferAttr();
                offerAttr.setShowType(KeyConsts.PROD_ATTR_SHOW_TYPE_E);
                offerAttr.setFieldName(key);
                offerAttr.setDefaultValue(Optional.ofNullable(val).map(Object::toString).orElse(null));
                offerAttr.setOfferId(offer.getOfferId());

                offerAttrs.add(offerAttr);
            }
        });

        return offerAttrs;
    }

    private static void addCateIdAttr(List<OfferAttr> offerAttrList, String offerId, String cateId) {
        OfferAttr attr = new OfferAttr();
        attr.setOfferId(offerId);
        attr.setFieldName("cateId");
        attr.setAttrId(SeqUtils.getNext("SEQ_ATTR_ID"));
        attr.setCname("商品分类ID");
        attr.setAttrValueTypeId("98C");
        attr.setStatusCd("1000");
        attr.setIsNull("F");
        attr.setIsEdit("F");
        attr.setShowType(KeyConsts.PROD_ATTR_SHOW_TYPE_E);
        attr.setDefaultValue(cateId);
        attr.setIfDefaultValue("T");
        attr.setHandlerClass("com.iwhalecloud.bss.kite.service.attr.handler.DefaultAttrHandler");
        offerAttrList.add(attr);
    }

    /**
     * 资费产品转换为OfferEffExpConfig
     * @return
     */
    @SuppressWarnings("unchecked")
    public static List<OfferEffExpConfig> convertToOfferEffExp(Map<String, Object> good) {
        Offer offer = convertOffer(good);
        List<OfferEffExpConfig> offerAttrs = new ArrayList<>();
        //资费产品信息
        List<Map<String, Object>> productCategroys = (List<Map<String, Object>>) good.get("productCategroy");
        if (KiteListUtils.isNotEmpty(productCategroys)) {
            for (Map<String, Object> productCategroy : productCategroys) {
                if ("pay".equals(KiteMapUtils.getString(productCategroy, "productType"))) {
                    List<Map<String, Object>> products = (List<Map<String, Object>>) productCategroy.get("products");
                    if (KiteListUtils.isNotEmpty(products)) {
                        Map<String, Object> product = products.get(0);
                        //资费产品也存到属性里面
                        OfferEffExpConfig effExpConfig = new OfferEffExpConfig();
                        //资费产品也放进去
                        effExpConfig.setOfferId(offer.getOfferId());
                        effExpConfig.setEffDate(offer.getEffDate());
                        effExpConfig.setExpDate(offer.getExpDate());
                        Map<String, String> effExpData = getConverEffExpType(product);
                        effExpConfig.setEffType(KiteMapUtils.getString(effExpData, "effType"));
                        if ("VALID".equals(KiteMapUtils.getString(product, "status"))) {
                            effExpConfig.setStatusCd("1000");
                        }
                        else {
                            effExpConfig.setStatusCd("1100");
                        }
                        offerAttrs.add(effExpConfig);
                    }
                }
            }
        }




        return offerAttrs;

    }

    @SuppressWarnings("unchecked")
    public static Map<String, String> getConverEffExpType(Map<String, Object> product) {
        List<Map<String, Object>> prodAttrs = (List<Map<String, Object>>) product.get("productAttrs");
        Map<String, String> rspData = new HashMap<String, String>();
        if (KiteListUtils.isNotEmpty(prodAttrs)) {
            prodAttrs.stream().map(prodAttr -> {
                if ("生效模式".equals(prodAttr.get("attrName")) || "失效模式".equals(prodAttr.get("attrName"))) {
                    List<Map<String, Object>> attrValues = (List<Map<String, Object>>) prodAttr.get("attrValues");
                    if (KiteListUtils.isNotEmpty(attrValues)) {
                        Map<String, Object> attrValue = attrValues.get(0);
                        if ("立即生效".equals(attrValue.get("valueName"))) {
                            rspData.put("effType", "1000");
                        }
                        if ("次月生效".equals(attrValue.get("valueName"))) {
                            rspData.put("expType", "1100");
                        }
                        if ("立即失效".equals(attrValue.get("valueName"))) {
                            rspData.put("expType", "1000");
                        }

                    }
                }

                return prodAttr;
            }).collect(Collectors.toList());
        }
        return rspData;
    }

    /**
     * 组装销售品属性
     * @param goodsAttrs
     * @param offerId
     * @return
     */
    private static List<OfferAttr> packageOfferAttr(List<Map<String, Object>> goodsAttrs, String offerId) {
        if (KiteListUtils.isNotEmpty(goodsAttrs)) {
            return goodsAttrs.stream().map(attr -> {
                convertFieldValue(attr);
                convertField(attr, getOfferConvertField());
                OfferAttr offerAttr = KiteMapUtils.mapToBean(attr, OfferAttr.class);
                offerAttr.setCname(offerAttr.getAttrName());
                offerAttr.setAttrName(offerAttr.getAttrName());
                offerAttr.setFieldName(offerAttr.getAttrCode());
                offerAttr.setIsEdit("true".equals(attr.get("edited")) ? KeyConsts.IFTRUE_T : KeyConsts.IFTRUE_F);
                //这里返回的下拉值是约束出来的 每个商品可能不一样 因此给一个唯一的key
                offerAttr.setAttrId(SeqUtils.getNext("SEQ_ATTR_ID"));
                offerAttr.setOfferId(offerId);
                cacheOfferAttrValue(offerAttr, attr);
                return offerAttr;
            }).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }


    /**
     * FIXME 这里有个问题 如果直接放进去 后面清了的话就找不回来了
     * @param offerAttr
     * @param attr
     */
    @SuppressWarnings("unchecked")
    private static void cacheOfferAttrValue(OfferAttr offerAttr, Map<String, Object> attr) {
        if (KeyConsts.DROPDOWN.equals(offerAttr.getAttrValueTypeId()) && KiteStringUtils.isNotBlank(offerAttr.getAttrId())) {
            List<Map<String, Object>> attrValues = (List<Map<String, Object>>) attr.get("attrValues");
            List<AttrValue> attrValueList = null;
            if (KiteListUtils.isNotEmpty(attrValues)) {
                attrValueList = new ArrayList<>();
                for (Map<String, Object> map : attrValues) {
                    AttrValue attrValue = new AttrValue();
                    attrValue.setAttrValue(KiteMapUtils.getString(map, "valueCode"));
                    attrValue.setAttrValueDesc(KiteMapUtils.getString(map, "valueName"));
                    attrValue.setAttrValueName(attrValue.getAttrValueDesc());
                    attrValue.setAttrValueSort("0"); //必填
                    attrValueList.add(attrValue);
                }
            }
            AttrValueCache.getInst().defaultPut(offerAttr.getAttrId(), Optional.ofNullable(attrValueList));
        }
    }

    /**
     * 销售品限制组装
     * @param good
     * @return
     */
    @SuppressWarnings("unchecked")
    public static List<OfferRestrict> convertOfferRestrict(Map<String, Object> good) {
        String offerId = KiteMapUtils.getString(good, "goodsSku");
        List<OfferRestrict> offerRestricts = new ArrayList<>();
        List<Map<String, Object>> saleProvinces = (List<Map<String, Object>>) good.get("saleProvinces");
        if (KiteListUtils.isNotEmpty(saleProvinces)) {
            for (Map<String, Object> saleProvince : saleProvinces) {
                List<Map<String, Object>> saleCities = (List<Map<String, Object>>) saleProvince.get("saleCities");
                if (KiteListUtils.isNotEmpty(saleCities)) {
                    //如果城市列表是空 且省份不是空 则返回省份
                    for (Map<String, Object> saleCity : saleCities) {
                        offerRestricts.add(packageOfferRestrict(offerId, KiteMapUtils.getString(saleCity, "cityCode")));
                    }
                }
                else if (StringUtils.isNotEmpty(KiteMapUtils.getString(saleProvince, "provinceCode"))) {
                    offerRestricts.add(packageOfferRestrict(offerId, KiteMapUtils.getString(saleProvince, "provinceCode")));
                }
            }
        }
        return offerRestricts;
    }

    private static OfferRestrict  packageOfferRestrict(String offerId, String areaCode) {
        OfferRestrict offerRestrict = new OfferRestrict();
        offerRestrict.setObjectType(KeyValues.INSTANCE_TYPE_10C);
        offerRestrict.setObjectId(offerId);
        offerRestrict.setDomainType(KeyValues.SALES_RESTRICATION_19S);
        offerRestrict.setDomainId(areaCode);
        offerRestrict.setRestricationFlag("0");
        offerRestrict.setState("00A");
        return offerRestrict;
    }

    /**
     * 销售品关系转换
     * @param good
     * @return
     */
    @SuppressWarnings("unchecked")
    public static List<OfferRelInfo> convertOfferRel(Map<String, Object> good) {
        List<OfferRelInfo> offerRelInfos = new ArrayList<>();
        Offer offer = convertOffer(good);
        if (KeyConsts.OFFER_TYPE_13.equals(offer.getOfferType())) {
            List<Map<String, Object>> saleGoods = (List<Map<String, Object>>) good.get("saleGoods");
            if (KiteListUtils.isNotEmpty(saleGoods)) {
                saleGoods.forEach(singleGood -> offerRelInfos.add(packageOfferRel(singleGood, offer)));
            }
        }
        return offerRelInfos;
    }

    /**
     * 销售品关系组装
     * @param singleGood
     * @param offer 融合或者套餐
     * @return
     */
    private static OfferRelInfo packageOfferRel(Map<String, Object> singleGood, Offer offer) {
        Offer singleOffer = convertOffer(singleGood);
        OfferRelInfo offerRelInfo = new OfferRelInfo();
        offerRelInfo.setaOfferId(offer.getOfferId());
        offerRelInfo.setaOfferName(offer.getOfferName());
        offerRelInfo.setOfferRelId(SeqUtils.getNext(TableConsts.OfferRel));
        offerRelInfo.setRelType(RelType.OFFER_REL_TYPE_100000.getCode());
        // 用z端销售品分类ID作为角色ID
        offerRelInfo.setRoleId(KiteMapUtils.getString(singleGood, "cateId"));
        offerRelInfo.setStatusCd(CoreDataPublic.PUB_C_0001_1000);
        offerRelInfo.setzOfferType(singleOffer.getOfferType());
        offerRelInfo.setzOfferId(singleOffer.getOfferId());
        offerRelInfo.setzOfferName(singleOffer.getOfferName());

        return offerRelInfo;
    }

    /**
     * 销售品明细转换
     * @param good
     * @return
     */
    @SuppressWarnings("unchecked")
    public static List<OfferDetail> convertOfferDetails(Map<String, Object> good) {
        List<OfferDetail> offerDetailList = new ArrayList<>();
        Offer offer = convertOffer(good);
        if (Objects.isNull(offer)) {
            return offerDetailList;
        }
        String cateId = KiteMapUtils.getString(good, "cateId");
        if (KeyConsts.OFFER_TYPE_13.equals(offer.getOfferType())) {
            List<Map<String, Object>> saleGoods = (List<Map<String, Object>>) good.get("saleGoods");
            if (KiteListUtils.isNotEmpty(saleGoods)) {
                saleGoods.forEach(singleGood -> offerDetailList.addAll(packageSingleDetail(singleGood, offer.getOfferId(), cateId)));
            }
        }
        else if (KeyConsts.OFFER_TYPE_15.equals(offer.getOfferType())) {
            offerDetailList.addAll(packageGroupGoodDetail(good, offer.getOfferId(), cateId));
        }
        else if (KeyConsts.OFFER_TYPE_11.equals(offer.getOfferType()) || LocalKeyConsts.OFFER_TYPE_MEMBER.equals(offer.getOfferType())) {
            offerDetailList.addAll(packageSingleDetail(good, offer.getOfferId(), cateId));
        }
        return KiteListUtils.distinctByPropertyName(offerDetailList, "detailId");
    }


    /**
     * 可选包明细转换
     * @param
     * @return
     */
    public static List<OfferDetail> convertAdditionalOfferDetails(String offerId) {
        //在处理转换可选包的时候已经放到缓存中
        List<OfferDetail> offerDetailList =  OfferDetailCache.get(offerId);
        return KiteListUtils.distinctByPropertyName(offerDetailList, "detailId");
    }

    /**
     * 组合商品明细组装
     * @param groupGood
     * @return
     */
    @SuppressWarnings("unchecked")
    private static List<OfferDetail> packageGroupGoodDetail(Map<String, Object> groupGood, String offerId, String cateId) {
        List<OfferDetail> offerDetailList = new ArrayList<>();
        List<Map<String, Object>> goodsCategroys = (List<Map<String, Object>>) groupGood.get("goodsCategroy");
        if (KiteListUtils.isNotEmpty(goodsCategroys)) {
            for (Map<String, Object> goodsCategroy : goodsCategroys) {
                List<Map<String, Object>> goods = (List<Map<String, Object>>) goodsCategroy.get("goods");
                if (KiteListUtils.isNotEmpty(goods)) {
                    goods.forEach(good -> {
                        OfferDetail offerDetail = new OfferDetail();
                        offerDetail.setOfferId(offerId);
                        offerDetail.setObjId(KiteMapUtils.getString(good, "goodsSku"));
                        offerDetail.setOfferObjectName(KiteMapUtils.getString(good, "goodsName"));
                        offerDetail.setRoleId(KiteMapUtils.getString(goodsCategroy, "categoryId"));
                        offerDetail.setRoleName(KiteMapUtils.getString(goodsCategroy, "cateName"));
                        offerDetail.setMinNum(KiteMapUtils.getString(good, "min_num"));
                        // 不能取分类下的数量约束
                        if (KiteStringUtils.isEmpty(offerDetail.getMinNum())) {
                            offerDetail.setMinNum("1");
                        }
                        offerDetail.setMaxNum(KiteMapUtils.getString(good, "max_num"));
                        if (KiteStringUtils.isEmpty(offerDetail.getMaxNum())) {
                            offerDetail.setMaxNum("1");
                        }
                        //销售品
                        offerDetail.setObjType(CoreDataOffer.OFF_C_0043_110000);
                        offerDetail.setStatusCd(CoreDataPublic.PUB_C_0001_1000);
                        String detailId = SeqUtils.getNext(TableConsts.OfferObjRel);
                        offerDetail.setDetailId(detailId);
                        offerDetail.setOfferObjRelId(detailId);
                        offerDetailList.add(offerDetail);
                    });
                }
            }
        }
        // 礼包的产品
        offerDetailList.addAll(packageSingleDetail(groupGood, offerId, cateId));

        return offerDetailList;
    }

    /**
     * 基础商品明细组装
     * @param singleGood
     * @param offerId 融合或者套餐 销售品标识
     * @return
     */
    @SuppressWarnings({
        "unchecked", "rawtypes"
    })
    private static List<OfferDetail> packageSingleDetail(Map<String, Object> singleGood, String offerId, String cateId) {
        List<OfferDetail> offerDetailList = new ArrayList<>();
        List<Map> productCategroys = (List<Map>) singleGood.get("productCategroy");
        List<Map> historyDataByNode = ProductsInfoTransfer.getHistoryDataByNode(singleGood, "products", KiteStringUtils.concatWithSymbol(LocalKeyConsts.PRODUCT_TYPE_BASE,LocalKeyConsts.PRODUCT_TYPE_ADD,SymbolConsts.COMMA));
        Offer singleOffer = convertOffer(singleGood);
        if (!KiteStringUtils.equals(offerId, singleOffer.getOfferId())) {
            Map singleGoodDetail = SpringUtil.getBean(IGoodsService.class).queryGoodsByOfferId(singleOffer.getOfferId());
            if (singleGoodDetail == null || !singleGoodDetail.containsKey("productCategroy")) {
                return Lists.newArrayList();
            }
            productCategroys = (List<Map>) singleGoodDetail.get("productCategroy");
            historyDataByNode = ProductsInfoTransfer.getHistoryDataByNode(singleGoodDetail, "products", KiteStringUtils.concatWithSymbol(LocalKeyConsts.PRODUCT_TYPE_BASE,LocalKeyConsts.PRODUCT_TYPE_ADD,SymbolConsts.COMMA));
        }
        if (KiteListUtils.isNotEmpty(productCategroys)) {
            for (Map productCategroy : productCategroys) {
                String productType = KiteMapUtils.getString(productCategroy, "productType");

                //如果是资费产品，不加载，用可选包去处理
                if (PRODUCT_TYPE_PAY.equals(productType)) {
                    continue;
                }

                convertFieldValue(productCategroy);
                convertField(productCategroy, getOfferConvertField());
                OfferObjRelRole offerObjRelRole = KiteMapUtils.mapToBean(productCategroy, OfferObjRelRole.class);
                offerObjRelRole.setRoleName(KiteMapUtils.getString(productCategroy, "cateName"));
                OfferObjRelRoleCache.getInst().defaultPut(offerObjRelRole.getRoleId(), Optional.ofNullable(offerObjRelRole));

                String minNum = NumberUtils.toInt(KiteMapUtils.getString(productCategroy, "min_num"), 1) + "";
                if (!StringUtils.equals(singleOffer.getOfferId(), offerId)) {
                    minNum = "0";
                }

                String maxNum = NumberUtils.toInt(KiteMapUtils.getString(productCategroy, "min_num"), 1) + "";
                List<Map> products = (List<Map>) productCategroy.get("products");
                if (KiteListUtils.isNotEmpty(products)) {
                    for (Map product : products) {
                        if (!STATUS_VALID.equals(KiteMapUtils.getString(product, "status"))) {
                            continue;
                        }
                        String productCode = KiteMapUtils.getString(product, "productCode");
                        OfferDetail offerDetail = new OfferDetail();
                        offerDetail.setOfferId(offerId);
                        offerDetail.setObjId(productCode);
                        offerDetail.setOfferObjectName(KiteMapUtils.getString(product, "productName"));
                        offerDetail.setRoleId(offerObjRelRole.getRoleId());
                        offerDetail.setRoleName(offerObjRelRole.getRoleName());
                        offerDetail.setMinNum(minNum);
                        offerDetail.setMaxNum(maxNum);
                        //产品
                        offerDetail.setObjType(CoreDataOffer.OFF_C_0043_100000);
                        offerDetail.setStatusCd(CoreDataPublic.PUB_C_0001_1000);
                        String detailId = SeqUtils.getNext(TableConsts.OfferObjRel);
                        offerDetail.setDetailId(detailId);
                        offerDetail.setOfferObjRelId(detailId);
                        offerDetailList.add(offerDetail);

                        product.put("productType", productType);
                        product.put("baseOfferId", offerId);
                        //产品缓存
                        ProductsInfoTransfer.convertProduct(product, cateId, offerId);
                        //历史节点销售品失效的产品属性缓存 集合不再次查询
                        ProdHisAttr prodHisAttr = new ProdHisAttr();
                        prodHisAttr.setProductId(productCode);
                        prodHisAttr.setAttrs(new ArrayList<>());
                        if(KiteListUtils.isNotEmpty(historyDataByNode)){
                            Map historyData = historyDataByNode.stream().filter(hisNode -> KiteStringUtils.equals(productCode, KiteMapUtils.getString(hisNode, "productCode"))).findFirst().orElse(null);
                            prodHisAttr.setAttrs(ProductsInfoTransfer.convertHisProdAttr(historyData));
                        }
                        String prodId = productCode;
                        if (GeneralSwitchUtils.isSwitchOpened(SwitchConsts.OFFER_PROVINCE_SCOPE)) {
                            prodId = KiteStringUtils.joinWith(SymbolConsts.UNDERLINE, prodId, offerId, ContextUtil.getLoginInfo().getUserInfo().getPostProvinceNbr());
                        }
                        ProdHisAttrCache.getInst().defaultPut(prodId, prodHisAttr);
                    }

                }

            }
        }
        return offerDetailList;
    }


    //处理资费产品转换可选包
    @SuppressWarnings("unchecked")
    public static List<OfferRelInfo> packageSingleDetail(Map<String, Object> good) {
        List<OfferRelInfo> offerRellList = new ArrayList<>();
        if (Objects.isNull(good)) {
            return offerRellList;
        }
        //资费产品的所挂的父销售品
        Offer offer = convertOffer(good);
        String cateId = KiteMapUtils.getString(good, "cateId");
        List<Map<String, Object>> productCategroys = (List<Map<String, Object>>) good.get("productCategroy");
        List<Map> historyDataByNode = ProductsInfoTransfer.getHistoryDataByNode(good, "products", LocalKeyConsts.PRODUCT_TYPE_PAY);
        packInValidPayCate(historyDataByNode,productCategroys);
        List<OfferRelInfo> offerRelInfoList = new ArrayList<>();
        if (KiteListUtils.isNotEmpty(productCategroys)) {
            int index = 1;
            List<OfferFeeDiscntShowRule> feeDiscntShowRules= new ArrayList<>();
            List<String> payProdIds = new ArrayList<>();
            for (Map<String, Object> productCategroy : productCategroys) {
                String productType = KiteMapUtils.getString(productCategroy, "productType");
                String cateName = KiteMapUtils.getString(productCategroy, "cateName");
                String categoryId = KiteMapUtils.getString(productCategroy, "categoryId");
                //产商品没有配置的暂时自己做区分
                if (KiteStringUtils.isEmpty(categoryId)) {
                    categoryId = offer.getOfferId() + "_" + index;
                    index++;
                }
                //只处理资费产品
                if (!PRODUCT_TYPE_PAY.equals(productType)) {
                    continue;
                }
                convertFieldValue(productCategroy);
                convertField(productCategroy, getOfferConvertField());

                //可选包的数量限制
                String minNum = KiteMapUtils.getString(productCategroy, "min_num");
                String maxNum = KiteMapUtils.getString(productCategroy, "max_num");
                //不能用这个最大最小值限制资费产品是否必选，这个最大最小只限制当前销售品下的资费产品是否订购的个数，不是订购的次数
//                String minNumStr = KiteStringUtils.isEmpty(minNum) ? "0" :NumberUtils.toInt(minNum, 1) + "";
//                String maxNumStr = KiteStringUtils.isEmpty(maxNum) ? "99" :NumberUtils.toInt(maxNum, 1) + "";
                String minNumStr = "0"; //KiteStringUtils.isEmpty(minNum) ? "0" :NumberUtils.toInt(minNum, 1) + "";
                String maxNumStr = "99" ;//KiteStringUtils.isEmpty(maxNum) ? "99" :NumberUtils.toInt(maxNum, 1) + "";

                List<Map<String, Object>> additionaloffers = (List<Map<String, Object>>) productCategroy.get("products");
                if (KiteListUtils.isEmpty(additionaloffers)) {
                    continue;
                }
                //区分可选和必选可选包，必选返回并实例化，可选将对应的规格A到offerRelCache中
                //资费产品转可选包
                for (Map<String, Object> additionalofferMap : additionaloffers) {
                    Offer additionaloffer = KiteMapUtils.mapToBean(ProductsInfoTransfer.transferField(additionalofferMap, coverFieldName()), Offer.class);
                    additionaloffer.setOfferType(CoreDataOffer.OFF_0005_12);
                    Map<String, Object> offerMap = !KiteMapUtils.isEmpty(additionaloffer.getOfferMap()) ? additionaloffer.getOfferMap() : new HashMap<>();
                    offerMap.put("discntCode", additionalofferMap.getOrDefault("jkFeeId", ""));
                    offerMap.put("payType", additionalofferMap.getOrDefault("payType", ""));
                    //处理售卖省份
                    //历史节点失效资费不返回售卖省份
                    if(!KiteStringUtils.equals(additionaloffer.getStatusCd(),"INVALID")){
                        dealSalesProvinces(additionalofferMap, offerMap);
                    }
                    additionaloffer.setOfferMap(offerMap);

                    //可选包属性处理
                    List<Map<String, Object>> additionalofferAttrs = (List<Map<String, Object>>) additionalofferMap.get("productAttrs");
                    ProductsInfoTransfer.convertPayProdAttr(additionalofferAttrs, additionaloffer.getOfferId(), cateId, offer.getOfferId());

                    //将转换后的可选包放到缓存中
                    String key = additionaloffer.getOfferId();
                    //存在失效属性时 历史节点和主节点均返回资费信息   只处理主节点资费
                    if(KiteStringUtils.equals(additionaloffer.getStatusCd(),"INVALID")){
                        if(payProdIds.contains(key)){
                            continue;
                        }
                    }else{
                        payProdIds.add(key);
                    }
                    if (GeneralSwitchUtils.isSwitchOpened(SwitchConsts.OFFER_PROVINCE_SCOPE)) {
                        key = KiteStringUtils.concatWithNnderline(key, ContextUtil.getLoginInfo().getUserInfo().getPostProvinceNbr());
                    }
                    ProdFeeCache.getInst().defaultPut(key, additionaloffer);

                    //将主套餐和可选包的关系放到offerRelCache中
                    OfferRelInfo offerRelInfo = new OfferRelInfo();
                    offerRelInfo.setaOfferId(offer.getOfferId());
                    offerRelInfo.setaOfferName(offer.getOfferName());
                    offerRelInfo.setzOfferId(additionaloffer.getOfferId());
                    offerRelInfo.setzOfferName(additionaloffer.getOfferName());
                    offerRelInfo.setMinNum(minNumStr);
                    offerRelInfo.setMaxNum(maxNumStr);
                    offerRelInfo.setzOfferType(CoreDataOffer.OFF_0005_12);
                    offerRelInfo.setRoleId(KiteMapUtils.getString(additionalofferMap, "cateId"));
                    offerRelInfo.setOfferRelId(SeqUtils.getNext(TableConsts.OfferRel));
                    offerRelInfo.setStatusCd(getOfferRelStatusCd(additionaloffer.getStatusCd()));
                    //当前资费产品的数量和最小值相等为必选,返回进行实例化
                    if (additionaloffers.size() == Integer.parseInt(minNumStr) && additionaloffers.size() == Integer.parseInt(maxNumStr)) {
                        offerRelInfo.setRelType(CoreDataOffer.OFF_0006_110000);
                        StringBuilder keySb = new StringBuilder();
                        keySb.append(additionaloffer.getOfferId()).append(SymbolConsts.UNDERLINE).append(CoreDataOffer.OFF_0006_110000).append("_getAOfferListRelsByz");
                        if (GeneralSwitchUtils.isSwitchOpened(SwitchConsts.OFFER_PROVINCE_SCOPE)) {
                            keySb.append(SymbolConsts.HASH).append(ContextUtil.getLoginInfo().getUserInfo().getPostProvinceNbr());
                        }
                        OfferRelCache.getInst().defaultPut(keySb.toString(), Collections.singletonList(offerRelInfo));
                    }
                    else {
                        offerRelInfo.setRelType(CoreDataOffer.OFF_0006_100000);
                        StringBuilder keySb = new StringBuilder();
                        keySb.append(additionaloffer.getOfferId()).append(SymbolConsts.UNDERLINE).append(CoreDataOffer.OFF_0006_100000).append("_getAOfferListRelsByz");
                        if (GeneralSwitchUtils.isSwitchOpened(SwitchConsts.OFFER_PROVINCE_SCOPE)) {
                            keySb.append(SymbolConsts.HASH).append(ContextUtil.getLoginInfo().getUserInfo().getPostProvinceNbr());
                        }
                        OfferRelCache.getInst().defaultPut(keySb.toString(), Collections.singletonList(offerRelInfo));
                    }
                    offerRellList.add(offerRelInfo);
                    offerRelInfoList.add(offerRelInfo);

                    //主套餐的详情
                    if (!KiteListUtils.isEmpty(OfferDetailCache.get(offer.getOfferId()))) {
                        OfferDetail mainOfferDetail = OfferDetailCache.get(offer.getOfferId()).get(0);
                        //将可选包和接入产品建立关系
                        OfferDetail offerDetail = new OfferDetail();
                        offerDetail.setOfferId(additionaloffer.getOfferId());
                        offerDetail.setObjId(mainOfferDetail.getObjId());
                        offerDetail.setOfferObjectName(mainOfferDetail.getOfferObjectName());
                        offerDetail.setObjType(CoreDataOffer.OFF_C_0043_100000);
                        offerDetail.setStatusCd(CoreDataPublic.PUB_C_0001_1000);
                        offerDetail.setRoleId(mainOfferDetail.getRoleId());
                        offerDetail.setRoleName(mainOfferDetail.getObjId());
                        offerDetail.setMinNum(minNum);
                        offerDetail.setMaxNum(maxNum);
                        String detailId = SeqUtils.getNext(TableConsts.OfferObjRel);
                        offerDetail.setDetailId(detailId);
                        offerDetail.setOfferObjRelId(detailId);

                        List<OfferDetail> offerDetailList = new ArrayList<>();
                        offerDetailList.add(offerDetail);
                        OfferDetailCache.getInst().defaultPut(key, offerDetailList);
                    }

                    //分组标识,资费产品属于不同的分组
                    CategoryOfferDTO categoryOfferDTO = new CategoryOfferDTO();
                    categoryOfferDTO.setCategoryId(categoryId);
                    categoryOfferDTO.setCateName(cateName);
                    categoryOfferDTO.setOfferId(additionaloffer.getOfferId());
                    categoryOfferDTO.setMaxNum(maxNum);
                    categoryOfferDTO.setMinNum(minNum);
                    CategoryOfferCache.getInst().defaultPut(additionaloffer.getOfferId(), categoryOfferDTO);
                    dealFeeDiscntShowRule(additionalofferMap,feeDiscntShowRules,offer.getOfferId());
                }
            }
            OfferFeeDiscntShowRuleCache.getInst().defaultPut(offer.getOfferId(), feeDiscntShowRules);
        }
        String key = offer.getOfferId();
        if (GeneralSwitchUtils.isSwitchOpened(SwitchConsts.OFFER_PROVINCE_SCOPE)) {
            key = KiteStringUtils.concatWithNnderline(offer.getOfferId(), ContextUtil.getLoginInfo().getUserInfo().getPostProvinceNbr());
        }
        OfferRelCache.getInst().defaultPut(key, offerRelInfoList);
        return offerRellList;
    }
//处理资费产品转换可选包
    @SuppressWarnings("unchecked")
    public static List<OfferFeeDiscntShowRule> listOfferFeeDiscntShowRule(Map<String, Object> good) {
        Offer offer = convertOffer(good);
        List<Map<String, Object>> productCategroys = (List<Map<String, Object>>) good.get("productCategroy");
        List<OfferRelInfo> offerRelInfoList = new ArrayList<>();
        List<OfferFeeDiscntShowRule> feeDiscntShowRules= new ArrayList<>();
        if (KiteListUtils.isNotEmpty(productCategroys)) {
            for (Map<String, Object> productCategroy : productCategroys) {
                //只处理资费产品
                String productType = KiteMapUtils.getString(productCategroy, "productType");
                if (!PRODUCT_TYPE_PAY.equals(productType)) {
                    continue;
                }
                List<Map<String, Object>> additionaloffers = (List<Map<String, Object>>) productCategroy.get("products");
                if (KiteListUtils.isEmpty(additionaloffers)) {
                    continue;
                }
                //资费产品转可选包
                for (Map<String, Object> additionalofferMap : additionaloffers) {
                    dealFeeDiscntShowRule(additionalofferMap,feeDiscntShowRules,offer.getOfferId());
                }
            }
            OfferFeeDiscntShowRuleCache.getInst().defaultPut(offer.getOfferId(), feeDiscntShowRules);
        }
        return feeDiscntShowRules;
    }


    /**
     * 成员商品
     * @param goods
     */
    public static void converMemberGoodsRestrictInfo(Map<String, Object> goods) {
        String parOfferId = KiteMapUtils.getString(goods, "goodsSku");
        List<Map<String, Object>> members = (List<Map<String, Object>>) goods.get("members");
        if (!KiteListUtils.isEmpty(members)) {
            List<OfferRelInfo> memOfferRelInfos = Lists.newArrayList();
            List<OfferRelInfo> addOfferRelInfos = Lists.newArrayList();
            for (Map<String, Object> member : members) {
                String memberType = KiteMapUtils.getString(member, "memberType");
                List<Map<String, Object>> memberGoodsList = (List<Map<String, Object>>) member.get("memberGoods");
                if (KiteListUtils.isEmpty(memberGoodsList)) {
                    continue;
                }
                for (Map<String, Object> memberGoods : memberGoodsList) {
                    // 获取上架省份
                    List<Map<String, Object>> saleProvinces = (List<Map<String, Object>>) memberGoods.get("saleProvinces");
                    if (Optional.ofNullable(saleProvinces).orElse(Lists.newArrayList()).stream().anyMatch(saleProvince -> KiteStringUtils.equals("09", KiteMapUtils.getStrValue(saleProvince, "provinceCode")))) {
                        // 如果是全国
                        SpringUtil.getBean(IUnicomRegionService.class).listSubRegion("09").forEach(region -> {
                            packageOfferRelInfo(parOfferId, memberType, region.getRegionCode(), memberGoods);
                        });
                    }
                    else {
                        Optional.ofNullable(saleProvinces).orElse(Lists.newArrayList()).stream().forEach(region -> {

                        });
                    }

                }
            }

            if (!KiteListUtils.isEmpty(memOfferRelInfos)) {
                //offerId + "_" + rstrType + "_" + offerType + "_listOfferRels";
                String key = KiteStringUtils.joinWith(SymbolConsts.UNDERLINE, parOfferId, CoreDataOffer.OFF_C_0005_1200, "_getAOfferListRelsByz");
                if (GeneralSwitchUtils.isSwitchOpened(SwitchConsts.OFFER_PROVINCE_SCOPE)) {
                    key = KiteStringUtils.joinWith(SymbolConsts.HASH, key, ContextUtil.getLoginInfo().getUserInfo().getPostProvinceNbr());
                }
                OfferRelCache.getInst().defaultPut(key, memOfferRelInfos);
            }
            if (!KiteListUtils.isEmpty(addOfferRelInfos)) {
                String key = KiteStringUtils.joinWith(SymbolConsts.UNDERLINE, parOfferId, RelType.OFFER_OBJ_REL_TYPE_120000.getCode(), "_getAOfferListRelsByz");
                if (GeneralSwitchUtils.isSwitchOpened(SwitchConsts.OFFER_PROVINCE_SCOPE)) {
                    key = KiteStringUtils.joinWith(SymbolConsts.HASH, key, ContextUtil.getLoginInfo().getUserInfo().getPostProvinceNbr());
                }
                OfferRelCache.getInst().defaultPut(key, memOfferRelInfos);
            }
        }
    }

    private static OfferRelInfo packageOfferRelInfo(String parOfferId, String memberType, String saleProvince, Map<String, Object> memberGoods) {
        OfferRelInfo offerRelInfo = new OfferRelInfo();
        offerRelInfo.setOfferRelId(SeqUtils.getNext(TableConsts.OfferRel));
        offerRelInfo.setaOfferId(parOfferId);
        offerRelInfo.setaOfferName(OfferCache.get(parOfferId).getOfferName());
        offerRelInfo.setRoleId(KiteMapUtils.getString(memberGoods, "cateId"));
        offerRelInfo.setzOfferId(KiteMapUtils.getString(memberGoods, "goodsSku"));
        offerRelInfo.setzOfferName(KiteMapUtils.getString(memberGoods, "goodsName"));
        offerRelInfo.setMaxNum(LocalKeyConsts.OFFER_REL_RSTR_MAX_NUM_DEFAULT);
        offerRelInfo.setMinNum(LocalKeyConsts.OFFER_REL_RSTR_MIN_NUM_DEFAULT);
        if (KiteStringUtils.equals(LocalKeyConsts.MEMBER_GOODS_TYPE_MEMBER, memberType)) {
            offerRelInfo.setzOfferType(LocalKeyConsts.OFFER_TYPE_16);
            offerRelInfo.setRelType(RelType.OFFER_OBJ_REL_TYPE_120000.getCode());
        }
        else {
            offerRelInfo.setzOfferType(LocalKeyConsts.OFFER_TYPE_11);
            offerRelInfo.setRelType(RelType.OFFER_OBJ_REL_TYPE_120000.getCode());
        }
        return offerRelInfo;
    }

    private static void removeProperty(Map<String, Object> map, Object bean) {
        PropertyDescriptor[] propertyDescriptors = BeanUtils.getPropertyDescriptors(bean.getClass());
        for (PropertyDescriptor property : propertyDescriptors) {
            String key = property.getName();
            if (map.containsKey(key)) {
                map.remove(key);
            }
        }
    }

    public static void convertField(Map<String, Object> reqMap, Multimap<String, String> fieldMap) {
        fieldMap.entries().forEach(entry -> {
            if (reqMap.containsKey(entry.getKey())) {
            	if (KeyConsts.INPUT.equals(reqMap.get("valueType")) && "defaultAttrValCodes".equals(entry.getKey())) {
            		reqMap.put(entry.getValue(), reqMap.get("attrValCodes"));
            	}
            	else {
            		reqMap.put(entry.getValue(), reqMap.get(entry.getKey()));
            	}
            }
        });

        fieldMap.entries().forEach(entry -> reqMap.remove(entry.getKey()));
    }

    /**
     * 值转换
     * @param reqMap
     */
    public static void convertFieldValue(Map<String, Object> reqMap) {
        reqMap.put("statusCd", CoreDataPublic.PUB_C_0001_1000);
        reqMap.put("isEdit", (reqMap.containsKey("edited") && (Boolean) reqMap.get("edited")) ? KeyConsts.IFTRUE_T : KeyConsts.IFTRUE_F);
        reqMap.put("isNull", (reqMap.containsKey("required") && (Boolean) reqMap.get("required")) ? KeyConsts.IFTRUE_F : KeyConsts.IFTRUE_T);
        reqMap.put("offerSysType", DcPublicCache.getPCode("20201121001", (String) reqMap.get("cateId")));
        reqMap.put("mainFlag", getMainFlag(reqMap));
        reqMap.put("offerDesc", reqMap.getOrDefault("goodsDescr", "")); //增加销售品描述
        if (reqMap.containsKey("effectTime") && Objects.nonNull(reqMap.get("effectTime"))) {
            String effectTime = KiteMapUtils.getString(reqMap, "effectTime");
            if (KiteStringUtils.isNum(effectTime)) {
                reqMap.put("effectTime", LocalDateTime.ofEpochSecond(Long.parseLong(effectTime) / 1000, 0, ZoneOffset.ofHours(8)));
            }
            else {
                DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                reqMap.put("effectTime", LocalDateTime.parse(effectTime, df));
            }
        }

        if (reqMap.containsKey("endTime") && Objects.nonNull(reqMap.get("endTime"))) {
            String endTime = KiteMapUtils.getString(reqMap, "endTime");
            if (KiteStringUtils.isNum(endTime)) {
                reqMap.put("endTime", LocalDateTime.ofEpochSecond(Long.parseLong(endTime) / 1000, 0, ZoneOffset.ofHours(8)));
            }
            else {
                DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                reqMap.put("endTime", LocalDateTime.parse(endTime, df));
            }
        }

        if (reqMap.containsKey("goodsType")) {
            String offerType = KiteMapUtils.getString(reqMap, "goodsType");
            if (KiteStringUtils.equals(GOODS_TYPE_SINGLE, offerType)||KiteStringUtils.equals(GOODS_TYPE_CLUSTER, offerType)) {
                // 成员商品
                if (!KiteObjectUtils.isEmpty(DcPublicCache.get("20210924001", (String) reqMap.get("cateId")))) {
                    reqMap.put("goodsType", KeyConsts.OFFER_TYPE_16);
                }
                else {
                    reqMap.put("goodsType", KeyConsts.OFFER_TYPE_11);
                }
            }
            else if (KiteStringUtils.equalsAny(offerType, GOODS_TYPE_GROUP, GOODS_TYPE_FUSE)) {
                reqMap.put("goodsType", KeyConsts.OFFER_TYPE_15);
            }
            else if (KiteStringUtils.equals(GOODS_TYPE_SALE, offerType)) {
                reqMap.put("goodsType", KeyConsts.OFFER_TYPE_13);
            }
        }

        if (reqMap.containsKey("valueType")) {
            String valueType = KiteMapUtils.getString(reqMap, "valueType");
            if (KiteStringUtils.equals(VALUE_TYPE_OPTION, valueType)) {
                reqMap.put("valueType", KeyConsts.DROPDOWN);
            }
            else if (KiteStringUtils.equals(VALUE_TYPE_INPUT, valueType)) {
                reqMap.put("valueType", KeyConsts.INPUT);
                reqMap.put("attrValue", KiteMapUtils.getString(reqMap, "attrValCodes"));
                reqMap.put("defaultValue", KiteMapUtils.getString(reqMap, "attrValCodes"));
            }
            else {
            	//商品属性没有valueType
            	String attrValCodes = KiteMapUtils.getString(reqMap, "attrValCodes");
            	JSONArray arr = reqMap.containsKey("attrValues") ? (JSONArray) reqMap.get("attrValues") : new JSONArray();
            	if (KiteObjectUtils.isEmpty(arr) && !attrValCodes.contains(",")) {
            		reqMap.put("valueType", KeyConsts.INPUT);
                    reqMap.put("attrValue", KiteMapUtils.getString(reqMap, "attrValCodes"));
                    reqMap.put("defaultValue", KiteMapUtils.getString(reqMap, "attrValCodes"));
            	}
            }
        }
        // 关键属性处理
        if (reqMap.containsKey("keyAttr")) {
            String keyAttr = KiteMapUtils.getString(reqMap, "keyAttr");
            if (KiteStringUtils.equals("true", keyAttr)) {
                reqMap.put("keyAttr", KeyConsts.PROD_ATTR_SHOW_TYPE_D);
                reqMap.put("isNull", "F");
                reqMap.put("isEdit", "F");
            }
            else {
                reqMap.put("keyAttr", KeyConsts.PROD_ATTR_SHOW_TYPE_M);
            }
        }
    }

    /**
     * key转换
     * @return
     */
    private static Multimap<String, String> getOfferConvertField() {
        Multimap<String, String> offerCoverFieldMap = ArrayListMultimap.create();
        offerCoverFieldMap.put("goodsSku", "offerId");
        offerCoverFieldMap.put("goodsType", "offerType");
        offerCoverFieldMap.put("goodsDescr", "offerDesc");
        offerCoverFieldMap.put("goodsCodes", "offerNbr");
        offerCoverFieldMap.put("goodsName", "offerName");
        offerCoverFieldMap.put("brand", "brandId");
        offerCoverFieldMap.put("effectTime", "effDate");
        offerCoverFieldMap.put("endTime", "expDate");
        offerCoverFieldMap.put("defaultAttrValCodes", "defaultValue");
        offerCoverFieldMap.put("valueType", "attrValueTypeId");
        offerCoverFieldMap.put("keyAttr", "showType");

        offerCoverFieldMap.put("categoryId", "roleId");
        offerCoverFieldMap.put("categoryId", "roleCd");

        return offerCoverFieldMap;
    }


    /**
     * 资费产品转可选包key转换
     * @return
     */
    public static Map<String, Object> coverFieldName() {
        Map<String, Object> fieldMap = new HashMap<String, Object>();
        fieldMap.put("productName", "offerName");
        fieldMap.put("productCode", "offerId");
        fieldMap.put("status", "statusCd");
        fieldMap.put("multiRentType", "createType");
        fieldMap.put("prodNbr", "categoryCode");
        fieldMap.put("productDesc", "offerDesc");
        return fieldMap;
    }

    /**
     * 判断附加产品
     * @param cateId
     * @return
     */
    public static boolean isAddRoleOffer(String offerId, String cateId) {
        DcPublic dcPublic = DcPublicCache.get("20201112001", cateId);
        return Objects.nonNull(dcPublic) || KiteStringUtils.equals(KeyConsts.MAIN_FLAG_0, Optional.ofNullable(OfferCache.get(offerId)).map(Offer::getMainFlag).orElse(""));
    }

    private static String getMainFlag(Map<String, Object> good) {
        List<Map<String, Object>> productCategroys = (List<Map<String, Object>>) good.get("productCategroy");
        if (KiteListUtils.isNotEmpty(productCategroys)) {
            for (Map<String, Object> productCategroy : productCategroys) {
                String productType = KiteMapUtils.getString(productCategroy, "productType");
                //只处理资费产品
                if (PRODUCT_TYPE_ADD.equals(productType)) {
                    return KeyConsts.MAIN_FLAG_0;
                }
            }
        }
        return KeyConsts.MAIN_FLAG_1;
    }

    /**
     * 处理产商品返回的售卖省份,英文逗号分隔
     * @param additionalofferMap 产商品接口原始数据
     * @param offerMap 极简实例属性
     */
    private static void dealSalesProvinces(Map<String, Object> additionalofferMap, Map<String, Object> offerMap) {
        StringBuffer salesProvinces = new StringBuffer();
        List<Map<String, Object>> offerSaleAreaList = (List<Map<String, Object>>) additionalofferMap.get("saleProvinces");
        if (KiteListUtils.isNotEmpty(offerSaleAreaList)) {
            offerSaleAreaList.forEach(offerSaleAreaMap -> {
                salesProvinces.append(offerSaleAreaMap.getOrDefault("provinceCode", "")).append(",");
            });
        }
        offerMap.put("saleProvince", salesProvinces.substring(0, salesProvinces.length() - 1));
    }

    /**
     * 资费显示规则处理
     * @param product
     * @param feeDiscntShowRules
     * @param offerId
     */
    private static void dealFeeDiscntShowRule(Map product,List<OfferFeeDiscntShowRule> feeDiscntShowRules,String offerId){
        Map<String,Object> discntShowRule = KiteMapUtils.getMap(product,"discntShowRule");
        if(null==discntShowRule){
            return;
        }
        List<Map<String, Object>> valueItems = (List<Map<String, Object>>) MapUtils.getObject(discntShowRule, "valueItems");
        if(null==valueItems){
            return;
        }
        String productCode = KiteMapUtils.getString(product,"offerId");
        productCode = StringUtils.isEmpty(productCode)?KiteMapUtils.getString(product,"productCode"):productCode;
        OfferFeeDiscntShowRule feeDiscntShowRule =feeDiscntShowRules.stream().filter(f->f.getAttrCode().equals(KiteMapUtils.getString(discntShowRule,"attrCode"))).findFirst().orElse(null);
            if(null==feeDiscntShowRule){
                //资费产品
                feeDiscntShowRule = new OfferFeeDiscntShowRule();
                feeDiscntShowRule.setShowRules(new ArrayList<>());
                List<ShowRule> showRules = feeDiscntShowRule.getShowRules();
                feeDiscntShowRule.setOfferId(offerId);
                feeDiscntShowRule.setAttrCode(KiteMapUtils.getString(discntShowRule,"attrCode"));
                String finalProductCode = productCode;
                valueItems.forEach(valueItem->{
                    ShowRule showRule = new ShowRule();
                    JSONObject showProd = new JSONObject();
                    List<JSONObject> list = new ArrayList<>();
                    showProd.put("prodId", finalProductCode);
                    showProd.put("show",MapUtils.getString(discntShowRule,"isRelation"));
                    list.add(showProd);
                    showRule.setValueCode(MapUtils.getString(valueItem,"valueCode"));
                    showRule.setValueName(MapUtils.getString(valueItem,"valueName"));
                    showRule.setShowProdIds(list);
                    showRules.add(showRule);
                });
                feeDiscntShowRules.add(feeDiscntShowRule);
            }else {

                        List<ShowRule> showRules = feeDiscntShowRule.getShowRules();
                String finalProductCode1 = productCode;
                valueItems.forEach(valueItem -> {
                            JSONObject showProd = new JSONObject();
                            showProd.put("prodId", finalProductCode1);
                            showProd.put("show",MapUtils.getString(discntShowRule,"isRelation"));
                            ShowRule showRule = showRules.stream().filter(sw -> sw.getValueCode().equals(MapUtils.getString(valueItem, "valueCode"))).findFirst().orElse(null);
                            if (null == showRule) {
                                showRule = new ShowRule();
                                List<JSONObject> list = new ArrayList<>();
                                list.add(showProd);
                                showRule.setValueCode(MapUtils.getString(valueItem, "valueCode"));
                                showRule.setValueName(MapUtils.getString(valueItem, "valueName"));
                                showRule.setShowProdIds(list);
                                showRules.add(showRule);
                            } else {
                                    showRule.getShowProdIds().add(showProd);
                            }
                        });

            }
    }
    /**
     * 资费产品转可选包历史节点打包
     * @return
     */
    private static void packInValidPayCate(List<Map> historyDataByNode, List<Map<String, Object>> productCategroys) {
        if(KiteListUtils.isNotEmpty(historyDataByNode)){
            Map<String, Object> productCategroyHis = new HashMap();
            productCategroyHis.put("productType","pay");
            productCategroyHis.put("cateName","失效资费虚拟分组");
            historyDataByNode.forEach(his->his.put("status","INVALID"));
            productCategroyHis.put("products",historyDataByNode);
            productCategroys.add(productCategroyHis);
        }
    }
    private static String getOfferRelStatusCd(String statusPay) {
        if(KiteStringUtils.equals(statusPay,"INVALID")){
            return KeyConsts2.PROD_STATUS_HIS_00C;
        }
        return KeyConsts2.PROD_STATUS_HIS_00A;
    }
}
